package com.cryptape.cita_wallet.activity.transfer;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.cryptape.cita_wallet.activity.EntrustActivity;
import com.cryptape.cita_wallet.bean.MaxDetailBean;
import com.cryptape.cita_wallet.constant.ConstantUtil;
import com.cryptape.cita_wallet.item.Chain;
import com.cryptape.cita_wallet.item.Currency;
import com.cryptape.cita_wallet.item.Token;
import com.cryptape.cita_wallet.item.Wallet;
import com.cryptape.cita_wallet.item.transaction.AppTransaction;
import com.cryptape.cita_wallet.service.ContractService;
import com.cryptape.cita_wallet.service.http.CITARpcService;
import com.cryptape.cita_wallet.service.http.CytonSubscriber;
import com.cryptape.cita_wallet.service.http.EthRpcService;
import com.cryptape.cita_wallet.service.http.TokenService;
import com.cryptape.cita_wallet.service.http.WalletService;
import com.cryptape.cita_wallet.util.CurrencyUtil;
import com.cryptape.cita_wallet.util.NumberUtil;
import com.cryptape.cita_wallet.util.db.DBWalletUtil;
import com.cryptape.cita_wallet.util.ether.EtherUtil;
import com.cryptape.cita_wallet.util.url.HttpCITAUrls;

import org.web3j.abi.datatypes.Address;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.generated.Uint256;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.utils.Numeric;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.concurrent.Callable;

import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

import static com.cryptape.cita_wallet.activity.transfer.TransferActivity.EXTRA_ADDRESS;
import static com.cryptape.cita_wallet.activity.transfer.TransferActivity.EXTRA_TOKEN;

/**
 * Created by dengming on 18/1/20.
 */

public class EntrustTransferPresenter0208 {

    private EntrustActivity mActivity;
    private TransferView mTransferView;

    private Token mToken;
    public Token mToken1;
    private double mTokenPrice = 0;
    private Wallet mWallet;
    private Currency mCurrency;

    private BigInteger mGasPrice, mGasLimit, mGas;
    private BigInteger mQuota, mQuotaLimit, mQuotaPrice;
    private String mData;
    public double mTokenBalance, mNativeTokenBalance, mTransferFee, mTokenHBalance;
    public final static String TYPE_LOCK_NATURE = "Nature";
    public final static String TYPE_LOCK_MIX = "Mix";
    public final static String TYPE_LOCK_EMPTY = "Empty";
    public MaxDetailBean mBean;
    public String mType;
    private String mLockAddress;

    public EntrustTransferPresenter0208(EntrustActivity activity, TransferView transferView) {
        mActivity = activity;
        mTransferView = transferView;

        init();
    }

    public void init() {

        EthRpcService.init(mActivity);
        CITARpcService.init(mActivity, HttpCITAUrls.CITA_NODE_URL);

        initTokenItem();
        getAddressData();
        initWalletData();
        getTokenBalance();
        initTransferFee();
    }

    public void getLockType() {
        mTransferView.startUpdateEthGasPrice();
        Observable.fromCallable(new Callable<String>() {
            @Override
            public String call() throws Exception {
                List<Type> datas = ContractService.lockAddress();
                if (datas != null && datas.size() == 1) {
                    return ((Address) datas.get(0)).getValue();
                }
                return null;
            }
        }).flatMap(new Func1<String, Observable<String>>() {
            @Override
            public Observable<String> call(String o) {
                return Observable.fromCallable(new Callable<String>() {
                    @Override
                    public String call() throws Exception {
                        if (o == null || o.equals("0x0000000000000000000000000000000000000000")) {
                            return null;
                        }
                        mLockAddress = o;
                        List<Type> datas = ContractService.orderDetail(o);
                        if (datas != null && datas.size() > 0) {
                            BigInteger type = ((Uint256) datas.get(0)).getValue();
                            Log.e("MainActivity", "lock type:" + type.intValue());
                            BigInteger natureType = (BigInteger.ONE);
                            BigInteger mixType = (new BigInteger("2"));
                            BigInteger emptyType = (new BigInteger("3"));
                            if (type.compareTo(natureType) == 0) {
                                return TYPE_LOCK_NATURE;
                            } else if (mixType.compareTo(type) == 0) {
                                return TYPE_LOCK_MIX;
                            } else if (emptyType.compareTo(type) == 0) {
                                return TYPE_LOCK_EMPTY;
                            }
                            return null;
                        }
                        return null;
                    }
                });
            }
        })
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<String>() {

                    @Override
                    public void onCompleted() {
                        mTransferView.updateEthGasPriceSuccess(BigInteger.ONE);
                    }

                    @Override
                    public void onError(Throwable e) {
                        mTransferView.updateEthGasPriceSuccess(BigInteger.ONE);
//                        mTransferView.transferEtherFail("获取地址失败");
                    }

                    @Override
                    public void onNext(String o) {
                        mType = o;
                        mActivity.setLockType1(o);
                        if (mType.equals(TYPE_LOCK_MIX)) {
                            mActivity.setLockType(TYPE_LOCK_MIX);
//                            mix_queryDetail();
                        }
                    }
                });
    }

    private void queryNativeBalance() {
        WalletService.getBalanceWithNativeToken(mActivity, mToken).subscribe(new Subscriber<Double>() {
            @Override
            public void onNext(Double balance) {
                mNativeTokenBalance = balance;
                mTransferView.updateNativeTokenBalance(balance);
            }

            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
                mActivity.dismissProgressCircle();
                Toast.makeText(mActivity, "查询余额失败", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onCompleted() {
                mActivity.dismissProgressCircle();

            }
        });
    }

    private void queryToken2Balnce() {
//        if(mToken1 != null)
        {
            WalletService.getBalanceWithToken(mActivity, mToken1).subscribe(new Subscriber<Double>() {
                @Override
                public void onNext(Double balance) {
                    mTokenHBalance = balance;
                    mActivity.updateMixHTokenBalance(balance);
                    mix_queryDetail();
                }

                @Override
                public void onError(Throwable e) {
                    mActivity.dismissProgressCircle();
                    Toast.makeText(mActivity, "查询余额失败", Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onCompleted() {

                }
            });
//            mix_queryDetail();
        }
    }


    public void getTokenBalance() {
        mActivity.showProgressCircle();
        WalletService.getBalanceWithToken(mActivity, mToken).subscribe(new Subscriber<Double>() {
            @Override
            public void onNext(Double balance) {
                mTokenBalance = balance;
                mTransferView.updateAnyTokenBalance(balance);

                if (mToken1 != null) {
                    queryToken2Balnce();
                } else {
                    queryNativeBalance();
                }
            }

            @Override
            public void onError(Throwable e) {
                mActivity.dismissProgressCircle();
                Toast.makeText(mActivity, "查询余额失败", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onCompleted() {

            }
        });
//        if(mToken1 != null) {
//            WalletService.getBalanceWithToken(mActivity, mToken1).subscribe(new CytonSubscriber<Double>() {
//                @Override
//                public void onNext(Double balance) {
//                    mTokenHBalance = balance;
//                    mActivity.updateMixHTokenBalance(balance);
//                }
//            });
//            mix_queryDetail();
//        }
//        WalletService.getBalanceWithNativeToken(mActivity, mToken).subscribe(new Subscriber<Double>() {
//            @Override
//            public void onNext(Double balance) {
//                mNativeTokenBalance = balance;
//                mTransferView.updateNativeTokenBalance(balance);
//            }
//
//            @Override
//            public void onError(Throwable e) {
//                e.printStackTrace();
//            }
//
//            @Override
//            public void onCompleted() {
//
//            }
//        });
    }

    private void getAddressData() {
        String address = mActivity.getIntent().getStringExtra(EXTRA_ADDRESS);
        mTransferView.updaterReceiveAddress(address);
    }

    private void initTokenItem() {
        mToken = mActivity.getIntent().getParcelableExtra(EXTRA_TOKEN);
//        mTransferView.updateTitleData("闪电兑换");
    }

    private void initWalletData() {
        mWallet = DBWalletUtil.getCurrentWallet(mActivity);
        mTransferView.updateWalletData(mWallet);
    }

    private void initTransferFee() {
        if (EtherUtil.isEther(mToken)) {
            initEthGasInfo();
            mTransferView.initTransferEditValue();
            initTokenPrice();
        } else {
            initCITAQuota();
        }
    }

    private void initEthGasInfo() {
//        mGasLimit = EtherUtil.isNative(mToken) ? ConstantUtil.QUOTA_TOKEN : ConstantUtil.QUOTA_ERC20;
        mGasLimit = ConstantUtil.QUOTA_ERC20_BIG;
        mTransferView.startUpdateEthGasPrice();
        EthRpcService.getEthGasPrice().subscribe(new CytonSubscriber<BigInteger>() {
            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
                mTransferView.updateEthGasPriceFail(e);
            }

            @Override
            public void onNext(BigInteger gasPrice) {
                mGasPrice = gasPrice;
                updateGasInfo();
                mTransferView.updateEthGasPriceSuccess(gasPrice);
                getLockType();
            }
        });
    }

    /**
     * get the price of token
     */
    private void initTokenPrice() {
        mCurrency = CurrencyUtil.getCurrencyItem(mActivity);
        TokenService.getCurrency(ConstantUtil.ETH, mCurrency.getName())
                .subscribe(new CytonSubscriber<String>() {
                    @Override
                    public void onNext(String price) {
                        if (TextUtils.isEmpty(price))
                            return;
                        try {
                            mTokenPrice = Double.parseDouble(price);
                            mTransferView.initTransferFeeView();
                        } catch (NumberFormatException e) {
                            e.printStackTrace();
                        }
                    }
                });
    }


    private void initCITAQuota() {
        mQuotaLimit = TextUtils.isEmpty(getTokenItem().getContractAddress()) ? ConstantUtil.QUOTA_TOKEN : ConstantUtil.QUOTA_ERC20;
        CITARpcService.getQuotaPrice(mWallet.address)
                .subscribe(new CytonSubscriber<String>() {
                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                    }

                    @Override
                    public void onNext(String quotaPrice) {
                        mQuotaPrice = new BigInteger(quotaPrice);
                        initQuotaFee();
                        mTransferView.initTransferFeeView();
                    }
                });

    }

    private void initQuotaFee() {
        mQuota = mQuotaLimit.multiply(mQuotaPrice);
        mTransferFee = NumberUtil.getEthFromWei(mQuota);
        mTransferView.updateCITAQuota(NumberUtil.getDecimalValid_8(mTransferFee) + getFeeTokenUnit());
    }

    public void updateQuotaLimit(BigInteger quotaLimit) {
        mQuotaLimit = quotaLimit;
        initQuotaFee();
    }

    public BigInteger getQuotaLimit() {
        return mQuotaLimit;
    }

    public void initGasLimit(AppTransaction appTransaction) {
        EthRpcService.getEthGasLimit(appTransaction)
                .subscribe(new CytonSubscriber<BigInteger>() {
                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                    }

                    @Override
                    public void onNext(BigInteger gasLimit) {
                        mGasLimit = gasLimit.multiply(ConstantUtil.GAS_LIMIT_PARAMETER);
                        updateGasInfo();
                    }
                });
    }

    public void handleEntrustTransferAction(String password, String transferValue, String receiveAddress, String type) {
        if (EtherUtil.isEther(mToken)) {
            if (ConstantUtil.ETH.equals(mToken.getSymbol())) {
                transferEth(password, transferValue, receiveAddress);
            } else {
                transferEntrustEthErc20(password, transferValue, receiveAddress, type);
            }
        }
    }

    /**
     * transfer origin token of ethereum
     *
     * @param value
     */
    private void transferEth(String password, String value, String receiveAddress) {
        EthRpcService.transferEth(mActivity, receiveAddress, value, mGasPrice, mGasLimit, mData, password)
                .subscribe(new CytonSubscriber<EthSendTransaction>() {
                    @Override
                    public void onError(Throwable e) {
                        mTransferView.transferCITAFail(e);
                    }

                    @Override
                    public void onNext(EthSendTransaction ethSendTransaction) {
                        Log.e("MainActivity", ethSendTransaction.getTransactionHash());
                        if (ethSendTransaction.hasError()) {
                            mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                        } else {
                            mTransferView.transferEtherSuccess(ethSendTransaction);
                        }
                    }
                });
    }

//    public void lockbalance(String password, String value, String receiveAddress, int decimal, String type, String contractAddress) {
//        subscribe = Observable.interval(5, TimeUnit.SECONDS)
//                .take(15)
//                .map(new Func1<Long, Boolean>() {
//                    @Override
//                    public Boolean call(Long aLong) {
//                        List<Type> datas = ContractService.lockbalance(contractAddress);
//                        if (datas != null && datas.size() >= 1) {
//                            BigInteger lockValue = new BigInteger(value).multiply(BigInteger.TEN.pow(decimal));
//                            BigInteger balance = ((Uint256) datas.get(0)).getValue();
//                            if (balance.subtract(lockValue).compareTo(BigInteger.ZERO) > 0) {
//                                return true;
//
//                            }
//                        }
//                        return false;
//                    }
//                })
//                .subscribeOn(Schedulers.newThread())
//                .observeOn(AndroidSchedulers.mainThread())
//                .subscribe(new Subscriber<Boolean>() {
//
//                    @Override
//                    public void onCompleted() {
//                        mTransferView.transferEtherFail("");
//                    }
//
//                    @Override
//                    public void onError(Throwable e) {
//                        mTransferView.transferEtherFail(e.getMessage());
//                    }
//
//                    @Override
//                    public void onNext(Boolean result) {
//                        if (result) {
//                            if (subscribe != null) {
//                                subscribe.unsubscribe();
//                            }
//                            lock_step3(password, value, receiveAddress);
//                        }
//                    }
//                });
//    }

    private void lock_step3(String password, String value, String receiveAddress, String type) {
        switch (type) {

            case TYPE_LOCK_NATURE:
                EthRpcService.lockNature(mActivity, mToken, receiveAddress, value, mGasPrice, mGasLimit, password)
                        .subscribe(new CytonSubscriber<EthSendTransaction>() {
                            @Override
                            public void onError(Throwable e) {
                                mTransferView.transferEtherFail(e.getMessage());
                            }

                            @Override
                            public void onNext(EthSendTransaction ethSendTransaction) {
                                if (ethSendTransaction.hasError()) {
                                    mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                                } else {
                                    mTransferView.transferEtherSuccess(ethSendTransaction);
                                }
                            }
                        });
            case TYPE_LOCK_EMPTY:
                EthRpcService.lockEmpty(mActivity, mToken, receiveAddress, value, mGasPrice, mGasLimit, password)
                        .subscribe(new CytonSubscriber<EthSendTransaction>() {
                            @Override
                            public void onError(Throwable e) {
                                mTransferView.transferEtherFail(e.getMessage());
                            }

                            @Override
                            public void onNext(EthSendTransaction ethSendTransaction) {
                                if (ethSendTransaction.hasError()) {
                                    mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                                } else {
                                    mTransferView.transferEtherSuccess(ethSendTransaction);
                                }
                            }
                        });

                break;
        }
    }

    private void lock_mix_append(String password, String value, String receiveAddress) {
        EthRpcService.lockMixAppend(mActivity, mToken, receiveAddress, value, mGasPrice, mGasLimit, password)
                .subscribe(new CytonSubscriber<EthSendTransaction>() {
                    @Override
                    public void onError(Throwable e) {
                        mTransferView.transferEtherFail(e.getMessage());
                    }

                    @Override
                    public void onNext(EthSendTransaction ethSendTransaction) {
                        if (ethSendTransaction.hasError()) {
                            mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                        } else {
                            mTransferView.transferEtherSuccess(ethSendTransaction);
                        }
                    }
                });
    }


    private void lockAppend(String password, String value, String receiveAddress) {
        EthRpcService.lockAppend(mActivity, mToken, receiveAddress, value, mGasPrice, mGasLimit, password)
                .subscribe(new CytonSubscriber<EthSendTransaction>() {
                    @Override
                    public void onError(Throwable e) {
                        mTransferView.transferEtherFail(e.getMessage());
                    }

                    @Override
                    public void onNext(EthSendTransaction ethSendTransaction) {
                        if (ethSendTransaction.hasError()) {
                            mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                        } else {
                            mTransferView.transferEtherSuccess(ethSendTransaction);
                        }
                    }
                });
    }

    Subscription subscribe = null;

//    public void singleLockExec(String password, String value, String receiveAddress, int decimal, String type){
//        if (!TextUtils.isEmpty(s) && !s.equals("0x0000000000000000000000000000000000000000")) {
//            lockAppend(password, value, s);
//        } else {
//            lock_step3(password, value, receiveAddress, type);
//            //mTransferView.transferEtherFail("获取地址失败");
//        }
//    }

    public void lock_step2(String password, String value, String receiveAddress, int decimal, String type) {
        Observable.fromCallable(new Callable<String>() {
            @Override
            public String call() throws Exception {
                List<Type> datas = ContractService.lockAddress();
                if (datas != null && datas.size() >= 1) {
                    return ((Address) datas.get(0)).getValue();
                }
                return null;
            }
        }).subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
//                        mTransferView.transferEtherFail("");
                    }

                    @Override
                    public void onError(Throwable e) {
                        mTransferView.transferEtherFail(e.getMessage());
                    }

                    @Override
                    public void onNext(String s) {
                        if (!TextUtils.isEmpty(s) && !s.equals("0x0000000000000000000000000000000000000000")) {
                            lockAppend(password, value, s);
                        } else {
                            lock_step3(password, value, receiveAddress, type);
                            //mTransferView.transferEtherFail("获取地址失败");
                        }
                    }
                });
    }


    private void transferEntrustEthErc20(String password, String value, String receiveAddress, String type) {
        {
            EthRpcService.transferEntrustErc20(mActivity, mToken, receiveAddress, value, mGasPrice, mGasLimit, password)
                    .subscribe(new CytonSubscriber<EthSendTransaction>() {
                        @Override
                        public void onError(Throwable e) {
                            mTransferView.transferEtherFail(e.getMessage());
                        }

                        @Override
                        public void onNext(EthSendTransaction ethSendTransaction) {
                            if (ethSendTransaction.hasError()) {
                                mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                            } else {
                                lock_step2(password, value, receiveAddress, mToken.decimals, type);
                            }
                        }
                    });
        }
    }

    private void transferMCoin(Context context, Token token, String receiveAddress, String mValue, String hValue,
                               BigInteger gasPrice, BigInteger gasLimit, String password, boolean isAppend) {
        EthRpcService.transferEntrustErc20(mActivity, mToken, receiveAddress, mValue, mGasPrice, mGasLimit, password)
                .subscribe(new CytonSubscriber<EthSendTransaction>() {
                    @Override
                    public void onError(Throwable e) {
                        mTransferView.transferEtherFail(e.getMessage());
                    }

                    @Override
                    public void onNext(EthSendTransaction ethSendTransaction) {
                        if (ethSendTransaction.hasError()) {
                            mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                        } else {
                            if (isAppend) {
                                lock_mix_append(password, mValue, receiveAddress);
                            } else {
                                transferHCoin(context, mToken1, receiveAddress, hValue, gasPrice, gasLimit, password);
                            }
                        }
                    }
                });
    }


    public void exec_Lock_MixNew(Context context, Token token, String receiveAddress, String value,
                                 BigInteger gasPrice, BigInteger gasLimit, String password) {
        lockMix(context, token, receiveAddress, value, gasPrice, gasLimit, password);

//        Observable.fromCallable(new Callable<String>() {
//            @Override
//            public String call() throws Exception {
//                List<Type> datas = ContractService.lockAddress();
//                if (datas != null && datas.size() >= 1) {
//                    return ((Address) datas.get(0)).getValue();
//                }
//                return null;
//            }
//        }).subscribeOn(Schedulers.newThread())
//                .observeOn(AndroidSchedulers.mainThread())
//                .subscribe(new Subscriber<String>() {
//                    @Override
//                    public void onCompleted() {
////                        mTransferView.transferEtherFail("");
//                    }
//
//                    @Override
//                    public void onError(Throwable e) {
//                        mTransferView.transferEtherFail(e.getMessage());
//                    }
//
//                    @Override
//                    public void onNext(String s) {
//                        if (!TextUtils.isEmpty(s) && !s.equals("0x0000000000000000000000000000000000000000")) {
//                            lock_mix_append(password, value, s);
//                        } else {
//                            lockMix(context,token,receiveAddress,value,gasPrice,gasLimit,password);
//                            //mTransferView.transferEtherFail("获取地址失败");
//                        }
//                    }
//                });
    }

    private void lockMix(Context context, Token token, String receiveAddress, String value,
                         BigInteger gasPrice, BigInteger gasLimit, String password) {
        EthRpcService.
                lockMix(context, token, receiveAddress, value, gasPrice, gasLimit, password)
                .subscribe(new Subscriber<EthSendTransaction>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {
                        mTransferView.transferEtherFail(e.getMessage());
                    }

                    @Override
                    public void onNext(EthSendTransaction ethSendTransaction) {
                        if (ethSendTransaction.hasError()) {
                            mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                        } else {
                            mTransferView.transferEtherSuccess(ethSendTransaction);
                        }
                    }
                })
        ;
    }

    private void transferHCoin(Context context, Token token, String receiveAddress, String value,
                               BigInteger gasPrice, BigInteger gasLimit, String password) {
        EthRpcService.transferEntrustErc201(mActivity, mToken1, receiveAddress, value, mGasPrice, mGasLimit, password)
                .subscribe(new CytonSubscriber<EthSendTransaction>() {
                    @Override
                    public void onError(Throwable e) {
                        mTransferView.transferEtherFail(e.getMessage());
                    }

                    @Override
                    public void onNext(EthSendTransaction ethSendTransaction) {
                        if (ethSendTransaction.hasError()) {
                            mTransferView.transferEtherFail(ethSendTransaction.getError().getMessage());
                        } else {
                            exec_Lock_MixNew(context, token, receiveAddress, value, gasPrice, gasLimit, password);
                        }
                    }
                });
    }

    public void execMixLock(Context context, Token token, String receiveAddress, String mValue,
                            String hValue, String password) {

        Observable.fromCallable(new Callable<String>() {
            @Override
            public String call() throws Exception {
                List<Type> datas = ContractService.lockAddress();
                if (datas != null && datas.size() >= 1) {
                    return ((Address) datas.get(0)).getValue();
                }
                return null;
            }
        }).subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
//                        mTransferView.transferEtherFail("");
                    }

                    @Override
                    public void onError(Throwable e) {
                        mTransferView.transferEtherFail(e.getMessage());
                    }

                    @Override
                    public void onNext(String s) {
                        if (!TextUtils.isEmpty(s) && !s.equals("0x0000000000000000000000000000000000000000")) {
                            transferMCoin(context, token, receiveAddress, mValue, hValue, mGasPrice, mGasLimit, password, true);
//                            lock_mix_append(password, mValue, s);
                        } else {
                            transferMCoin(context, token, receiveAddress, mValue, hValue, mGasPrice, mGasLimit, password, false);
                            //mTransferView.transferEtherFail("获取地址失败");
                        }
                    }
                });

    }

    private void mix_queryDetail() {
        Observable.fromCallable(new Callable<MaxDetailBean>() {
            @Override
            public MaxDetailBean call() throws Exception {

                List<Type> aBalance = ContractService.aTokenBalance();
                if (aBalance != null && aBalance.size() > 0) {
                    BigInteger balance1 = ((Uint256) aBalance.get(0)).getValue();
                    Log.e("MainActivity", "A Balance:" + balance1.toString());
                }

                List<Type> bBalance = ContractService.bTokenBalance();
                if (bBalance != null && bBalance.size() > 0) {
                    BigInteger balance2 = ((Uint256) bBalance.get(0)).getValue();
                    Log.e("MainActivity", "B Balance:" + balance2.toString());
                }


                List<Type> datas = ContractService.queryMixDetail();
                if (datas == null || datas.size() < 3) {
                    return null;
                }
                int rateBase = ((Uint256) datas.get(0)).getValue().intValue();
                int rate = ((Uint256) datas.get(1)).getValue().intValue();
                long unLockTime = ((Uint256) datas.get(2)).getValue().intValue();
                Log.e("MainActivity", "rateBase:" + rateBase + "  rate:" + rate + " unLockTime:" + unLockTime);
                MaxDetailBean bean = new MaxDetailBean();
                bean.setRateM(rate);
                bean.setRateH(rateBase);
                bean.setUnLockTime(unLockTime);

                return bean;
            }
        })
//                .flatMap(new Func1<String, Observable<MaxDetailBean>>() {
//            @Override
//            public Observable<MaxDetailBean> call(String s) {
//                return Observable.fromCallable(new Callable<MaxDetailBean>() {
//                    @Override
//                    public MaxDetailBean call() throws Exception {
//                        if (!TextUtils.isEmpty(s) && !s.equals("0x0000000000000000000000000000000000000000")){
//                            return null;
//                        }
//                        List<Type> datas = ContractService.queryMixDetail();
//                        if(datas == null || datas.size() <3){return null;
//                        }
//                        int rateBase = ((Uint256)datas.get(0)).getValue().intValue();
//                        int rate = ((Uint256)datas.get(1)).getValue().intValue();
//                        long unLockTime = ((Uint256)datas.get(2)).getValue().intValue();
//                        MaxDetailBean bean = new MaxDetailBean();
//                        bean.setRate(rate);
//                        bean.setRateBase(rateBase);
//                        bean.setUnLockTime(unLockTime);
//
//                        return bean;
//                    }
//                });
//            }
//        }).
                .subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<MaxDetailBean>() {
                    @Override
                    public void onCompleted() {
                        mActivity.dismissProgressCircle();
//                        mTransferView.transferEtherFail("");
                    }

                    @Override
                    public void onError(Throwable e) {
                        mActivity.dismissProgressCircle();
                        Toast.makeText(mActivity, "查询委托详情失败", Toast.LENGTH_SHORT).show();

                    }

                    @Override
                    public void onNext(MaxDetailBean s) {
                        if (s != null) mBean = s;
                    }
                });
    }

    private void updateGasInfo() {
        mGas = mGasPrice.multiply(mGasLimit);
        mTransferFee = NumberUtil.getEthFromWei(mGas);
        mTransferView.initTransferFeeView();
    }

    /**
     * @param gasPrice wei
     */
    public void updateGasPrice(BigInteger gasPrice) {
        mGasPrice = gasPrice;
        updateGasInfo();
    }

    public void updateGasLimit(BigInteger gasLimit) {
        mGasLimit = gasLimit;
        updateGasInfo();
    }

    public void updateData(String data) {
        mData = data;
    }

    public String getData() {
        return mData;
    }

    public Token getTokenItem() {
        return mToken;
    }

    public Wallet getWalletItem() {
        return mWallet;
    }

    public BigInteger getGasLimit() {
        return mGasLimit;
    }

    public boolean isTransferFeeEnough() {
        return mNativeTokenBalance - mTransferFee >= 0;
    }

    /**
     * Check whether transfer value is bigger than balance of wallet
     *
     * @return
     */
    public boolean checkTransferValueMoreBalance(String transferValue) {
        if (isNativeToken()) {
            return Double.parseDouble(transferValue) > (mNativeTokenBalance - mTransferFee);
        } else {
            return Double.parseDouble(transferValue) > mTokenBalance;
        }
    }

    public String balanceSubFee() {
        if (isNativeToken()) {
            return NumberUtil.getDecimalValid_8(new BigDecimal(mNativeTokenBalance).subtract(new BigDecimal(mTransferFee)).doubleValue());
        } else {
            return NumberUtil.getDecimalValid_8(mTokenBalance);
        }
    }

    public String getTransferFee() {
        if (mTokenPrice > 0 && EtherUtil.isMainNet()) {
            return NumberUtil.getDecimalValid_8(mTransferFee) + getFeeTokenUnit()
                    + " ≈ " + mCurrency.getSymbol() + " "
                    + NumberUtil.getDecimalValid_2(mTransferFee * mTokenPrice);
        } else {
            return NumberUtil.getDecimalValid_8(mTransferFee) + getFeeTokenUnit();
        }
    }

    public BigInteger getGasPrice() {
        return mGasPrice;
    }


    public boolean isNativeToken() {
        return TextUtils.isEmpty(mToken.getContractAddress());
    }

    public boolean isEther() {
        return Numeric.toBigInt(mToken.getChainId()).compareTo(BigInteger.ZERO) < 0;
    }

    public String getFeeTokenUnit() {
        if (EtherUtil.isEther(mToken)) {
            return " " + ConstantUtil.ETH;
        } else {
            Chain chain = DBWalletUtil.getChainItemFromCurrentWallet(mActivity, mToken.getChainId());
            return chain == null || TextUtils.isEmpty(chain.tokenSymbol) ? "" : " " + chain.tokenSymbol;
        }
    }

}
